import React, { useCallback, useState, useEffect, useRef } from 'react';
import { message, Modal, Spin } from 'antd';

import store from '@/store';
import { observer } from 'mobx-react-lite';
import Printer, { RefProps } from './Printer';
import Setting from './Setting';
import HeaderLayout from '@/layout/Header';
import FooterLayout from '@/layout/Footer';
import PrintFileList, { FileList, File } from './PrintFileList';
import useIpcSend, { TypeKey as IpcSendType } from '@/hooks/useIpcSend';
import useIpcListen, { TypeKey as IpcListenType } from '@/hooks/useIpcListen';
import Styles from './index.module.less';

export const Home: React.FC = React.memo(
    observer(() => {
        const printerRef = useRef<RefProps>();
        const [setting, setSetting] = useState(false);
        const [fileListDrawer, setFileListDrawer] = useState(false);
        const [printFiles, setPrintFileList] = useState<FileList>([]);

        const { app } = store.useStore();
        const ipcListen = useIpcListen();
        const ipcRender = useIpcSend(IpcSendType.print);
        const [modal, ModalSpace] = Modal.useModal();

        ipcListen(IpcListenType.printSuccess, (_: unknown, value) => {
            message.success(value as string);
        });
        ipcListen(IpcListenType.printFail, (_: unknown, value) => {
            message.error(value as string);
        });
        ipcListen(IpcListenType.appName, (_: unknown, value: string) => {
            app.setAppName(value);
        });
        ipcListen<FileList>(IpcListenType.printFile, (_, fileList) => {
            fileList = fileList.map((item) => ({
                ...item,
                filename: decodeURIComponent(item.filename),
                url: decodeURIComponent(item.url),
                status: 'normal'
            }));
            setPrintFileList(fileList);
            setFileListDrawer(true);
            message.destroy();

            const tips =
                import.meta.env.VITE_PRIVATE === '1'
                    ? `已收到网络创建的打印任务如下：`
                    : `已收到网络创建的打印任务如下`;
            message.success(tips);
        });

        const restartPrinterServices = () => {
            app.awakenPrintService();
        };

        useEffect(() => {
            const key = Date.now();
            if (app.isAwakenFail) {
                message.error({
                    key,
                    content: (
                        <>
                            <span>
                                打印服务唤醒失败，请重启程序或点击重试重启打印服务。
                            </span>
                            <span
                                onClick={restartPrinterServices}
                                className={Styles.restartServices}
                            >
                                重试
                            </span>
                        </>
                    ),
                    duration: -1
                });
            }
            return () => message.destroy(key);
        }, [app.isAwakenFail]);

        // 删除打印一条打印任务数据
        const deleteFile = useCallback(
            (_: File, index: number) => {
                printFiles.splice(index, 1);
                setPrintFileList([...printFiles]);
            },
            [printFiles]
        );

        // 预览任务
        const previewFile = useCallback((file: File) => {
            ipcRender('open:url', file.url);
        }, []);

        // 文件打印成功
        const successPrint = (
            printQueueSuccess: Array<{
                path: string;
                status: boolean;
                url: string;
            }>
        ) => {
            for (const file of printFiles) {
                const printItem = printQueueSuccess.find(
                    (item) => item.url === file.url
                );
                if (!printItem) continue;
                file.status = printItem.status ? 'success' : 'error';
            }
            setPrintFileList(printFiles);
        };

        // 打印文件
        const printFile = useCallback(
            (fileList = printFiles) => {
                if (!fileList.length) {
                    return setFileListDrawer(true);
                }
                const { printer } = printerRef.current!.getPrinterOption();
                if (!printer) return message.error('请先选择打印机');

                modal.confirm({
                    content: `确认要打印选择的文件吗？  累计：(${fileList.length})份`,
                    okText: '确认',
                    cancelText: '取消',
                    onOk: () => {
                        toggleSetting(false);
                        visibleFileListDrawer(false);
                        app.printFile({
                            printer,
                            color: 'monochrome',
                            fileList: fileList.map((item) => item.url)
                        }).then((res) => {
                            if (res.data.code !== 200)
                                throw new Error(res.data.result);
                            message.success(
                                `打印成功，累计: ${res.data.result.length}份`
                            );
                            successPrint(res.data.result);
                        });
                    }
                });
            },
            [printFiles]
        );

        // 显示或隐藏文件列表抽屉
        const visibleFileListDrawer = useCallback((visible: boolean) => {
            setFileListDrawer(visible);
        }, []);

        // 显示或隐藏设置抽屉
        const toggleSetting = useCallback((visible: boolean) => {
            setSetting(visible);
        }, []);

        // 添加本地打印任务
        const addLocalTask = useCallback(() => {
            ipcRender('add:local:task');
        }, []);

        // 唤醒打印服务
        useEffect(() => {
            app.awakenPrintService();
        }, []);

        return (
            <section className={Styles.home}>
                {ModalSpace}
                <HeaderLayout toggleSetting={toggleSetting} />
                <section className={Styles.container}>
                    <Printer
                        ref={printerRef}
                        onFinish={printFile}
                        toggleSetting={toggleSetting}
                        toggleFileListDrawer={visibleFileListDrawer}
                        fileListCount={printFiles.length}
                        addLocalTask={addLocalTask}
                    />
                    <PrintFileList
                        toggleFileListDrawer={visibleFileListDrawer}
                        visible={fileListDrawer}
                        fileList={printFiles}
                        delete={deleteFile}
                        preview={previewFile}
                        printFile={printFile}
                        cleanTask={() => setPrintFileList([])}
                    />
                    <Setting toggleSetting={toggleSetting} visible={setting} />
                </section>

                <Spin
                    spinning={app.awaken.loading}
                    percent={'auto'}
                    tip="唤醒打印服务中..."
                    fullscreen
                />
                <FooterLayout />
            </section>
        );
    })
);
